#ifdef arm
#include "Fpga.h"
#include "Mcu.h"
#endif
#include "Setting.h"
#include <unistd.h>
static void setImageSaturability(uint32_t index, uint32_t type);
static void setISensorCalibration(uint32_t value, uint32_t type);
static void setImageSharpness(uint32_t value, uint32_t type);
static void setImageColorB(uint32_t value, uint32_t type);
static void setImageColorR(uint32_t value, uint32_t type);
static void setImageGamma(uint32_t value, uint32_t type);
static void setImageDenoise(uint32_t value, uint32_t type);
static void setImageContrast(uint32_t value, uint32_t type);
static void setImageBrightness(uint32_t value, uint32_t type);
static void setLedBrightness(uint32_t value, uint32_t type);
static void setImageclippedMode(uint32_t value, uint32_t type);
static void setImageFreeze(uint32_t value, uint32_t type);
static void setImageZoom(uint32_t value, uint32_t type);
static void setImageAwb(uint32_t value, uint32_t type);
static void setStripeCorrect(uint32_t value, uint32_t type);
static void setCCMEN(uint32_t value, uint32_t type);
static void setImageRotateAngle(uint32_t index, uint32_t type);
static void setImageDLC(uint32_t index, uint32_t type);
static void setImageDPC(uint32_t index, uint32_t type);
static void setImageLens(uint32_t index, uint32_t type);
void (*setFpga[])( uint32_t value , uint32_t type) =
{
        setImageSaturability,
        setImageColorR,
        setImageColorB,
        setImageSharpness,
        setISensorCalibration,
        setImageGamma,
        setImageDenoise,
        setImageContrast,
        setImageBrightness,
        setLedBrightness,
        setImageclippedMode,
        setStripeCorrect,
        setImageDLC,
        setImageDPC,
        setImageLens,
        setImageFreeze,
        setImageZoom,
        setImageAwb,
        setCCMEN,
        setImageRotateAngle,
};

void checkSettingValue(int index, int* value)
{
    switch (index) {
    case ImageSaturability_Index:
    case ImageColorR_Index:
    case ImageColorB_Index:
    case ImageContrast_Index:
    case ImageBrightness_Index:
    case Ledbrightness_Index:
        if ((*value) < 0) {
            (*value) = 0;
        } else if ((*value) > 9) {
            (*value) = 9;
        }
        break;
    case ImageRotate:
    case ImageDenoise_Index:
        if ((*value) < 0) {
            (*value) = 0;
        } else if ((*value) > 3) {
            (*value) = 3;
        }
        break;

    case ImageDLC:
    case ImageDPC:
    case ImageLens:
    case ImageSharpness_Index:
        if ((*value) < 0) {
            (*value) = 0;
        } else if ((*value) > 4) {
            (*value) = 4;
        }
        break;

    case ImageGamma_Index:
        if ((*value) < 0) {
            (*value) = 0;
        } else if ((*value) > 11) {
            (*value) = 11;
        }
        break;

    case ImageZoom_Index:
        if ((*value) > 3) {
            (*value) = 0;
        }
        break;
    case ImageCalibration_Index:
        if ((*value) < 0) {
            (*value) = 0;
        } else if ((*value) > 15) {
            (*value) = 15;
        }

    case StripeCorrect_Index:
        if ((*value) < 0) {
            (*value) = 0;
        } else if ((*value) > 30) {
            (*value) = 30;
        }
        break;
    }
}

/* 设置饱和度 */
static uint32_t saturabilityValue[][10] = {
    {0x0266,0x0336,0x0404,0x04D2,0x05A0,0x05E0,0x0620,0x0660,0x06A0,0x06E0},//6946
    {0x0266,0x02CE,0x0334,0x039A,0x0400,0x04CC,0x0532,0x0598,0x05A0,0x05FF}//9734
};

static void setImageSaturability(uint32_t index, uint32_t type)
{
#ifdef arm
    uint32_t temp = Fpga::getInstance()->readRegister(0x4019c);
    uint32_t mask = 0x1FFF;
    uint8_t t = (type==0x69?0:1);
    mask = mask << 16;
    temp = temp & (~mask);
    temp = temp | (saturabilityValue[t][index] << 16);
    Fpga::getInstance()->writeRegister(0x4019c, temp);
    qDebug()<<"setImageSaturability, value = "<<temp;
#endif
}


/* 设置色偏R */
static uint32_t colorRValue[][10] = {
    {0x0400,0x0466,0x04B3,0x0500,0x054D,0x05A0,0x05F3,0x0646,0x0699,0x6EB},
    {0x0280,0x029A,0x02E6,0x0333,0x0380,0x0400,0x0466,0x04B3,0x0500,0x054D}
};

static void setImageColorR(uint32_t value, uint32_t type)
{
#ifdef arm
    uint8_t t = (type==0x69?0:1);
    Fpga::getInstance()->writeRegister(0x401b8, colorRValue[t][value]);
#endif
    qDebug()<<"setImageColorR, value = "<<colorRValue[t][value];
}


/* 设置色偏B */
static uint32_t colorBValue[][10] = {
    {0x0380,0x0400,0x041A,0x0466,0x04B3,0x0500,0x0540,0x0580,0x05C0,0x600},
    {0x0280,0x029A,0x02A0,0x02E6,0x0333,0x0380,0x0400,0x041A,0x0466,0x04B3}
};
static void setImageColorB(uint32_t value,uint32_t type)
{
#ifdef arm
    uint8_t t = (type==0x69?0:1);
    uint32_t temp = Fpga::getInstance()->readRegister(0x4019c);
    uint32_t mask = 0x1FFF;
    temp = temp & (~mask);
    temp = temp | colorBValue[t][value];
    Fpga::getInstance()->writeRegister(0x4019c, temp);
    qDebug()<<"setImageColorB, value = "<<temp;
#endif
}

/* 锐度 */
static uint32_t sharpnessValue[][5] = {
    {0x00,0x88,0x89,0x9f,0x8f},//00228 6946
    {0x00,0x00,0x08,0x09,0x0f},//00228 9734
    {0x00,0x01,0x01,0x00,0x01},//001c 6946
    {0x00,0x00,0x00,0x00,0x00},//001c 9734
};
/* 设置锐度 */
static void setImageSharpness(uint32_t value, uint32_t type)
{
    qDebug()<<QString("value:%1, type:%2").arg(value).arg(type);
    uint8_t t = (type==0x69?0:1);
    Fpga::getInstance()->writeRegister(0x4001c, sharpnessValue[t+2][value]);
    Fpga::getInstance()->writeRegister(0x40228, sharpnessValue[t][value]);
}

/* 设置sensor校准 */
static void setISensorCalibration(uint32_t value, uint32_t type) {
    qDebug()<<__FUNCTION__<<QString("value:0X%1, type:%2").arg(0x48+value,0,16).arg(type);
    Mcu::getInstance()->setSensorCalibrationMessage(0x48+value);
    usleep(50*1000);
}

/*操作电阻，0-30*/
static void setStripeCorrect(uint32_t value, uint32_t type) {
    qDebug()<<"setISensorCalibration, value = "<<value;
    Mcu::getInstance()->setStripeCalibrationMessage(value);
    usleep(50*1000);
}

extern void setGamma(int index);
/* 设置gamma */
static void setImageGamma(uint32_t value, uint32_t type)
{
    qDebug()<<"setImageGamma, value = "<<value;
    setGamma(value);
}

static uint32_t DenoiseValue[] = {
    0x00,0x80,0x90,0xf0
};

static void setImageDenoise(uint32_t value, uint32_t type) {
    //qDebug()<<"0x40230 setImageDenoise, no ok" <<value<<"-"<<DenoiseValue[value];
    uint32_t v = Fpga::getInstance()->readRegister(0x40228);
    v &= (~0X000000F0);
    Fpga::getInstance()->writeRegister(0x40228, v|DenoiseValue[value]);
}

extern void setContrast(int index);
/* 设置对比度 */
static void setImageContrast(uint32_t value, uint32_t type) {
    qDebug()<<"setImageContrast, value = "<<value;
    setContrast(value);
}

/* 设置图像亮度 */
static void setImageBrightness(uint32_t value, uint32_t type)
{
#ifdef arm
    uint32_t shift = 0;

    shift = 1;
    value = (value) * 10;
    value = value | (shift << 16);
    Fpga::getInstance()->writeRegister(0x40200, value);
#endif
}

static void setLedBrightness(uint32_t value, uint32_t type)
{
    qDebug()<<"setLedBrightness, value = "<<value + 1;
    if (value >=0 && value <= 9)
        Fpga::getInstance()->writeRegister(0x38, value + 1);
    else if (value == 10)//off
        Fpga::getInstance()->writeRegister(0x34, 0);
    else if (value == 11)//on
        Fpga::getInstance()->writeRegister(0x34, 1);

}

static void setImageclippedMode(uint32_t value, uint32_t type)
{
#ifdef arm
    qDebug()<<"setImageclippedMode, value = "<<value;
    Fpga::getInstance()->writeRegister(0x1c, value);
#endif
}

static void setImageRotateAngle(uint32_t index, uint32_t type)
{
    qDebug()<<"setImageRotateAngle, index = "<<index;
#ifdef arm
    Fpga::getInstance()->writeRegister(0x401F8, index);
#endif
}

void setImageFreeze(uint32_t value, uint32_t type)
{
    if (value == 0) {
        Fpga::getInstance()->writeRegister(0x20, 0);
    } else {
        Fpga::getInstance()->writeRegister(0x20, 1);
    }
}

constexpr size_t AWB_ENABLE_ADDR{ 0x4000c };
constexpr int    AWB_ENABLE_BIT{ 0 };
constexpr int    AWB_ENABLE_VALUE{ 1 };
constexpr int    AWB_DISABLE_VALUE{ 0 };
constexpr int    AWB_CONFIG_ADDR{ 0x40014 };
constexpr int    AWB_CONFIG_BIT{ 1 };
constexpr int    AWB_CONFIG_START_VALUE{ 1 };
constexpr int    AWB_CONFIG_END_VALUE{ 0 };
constexpr int    AWB_CONFIG_R_START_BIT{ 16 };
constexpr int    AWB_CONFIG_R_END_BIT{ 28 };
constexpr int    AWB_CONFIG_B_START_BIT{ 0 };
constexpr int    AWB_CONFIG_B_END_BIT{ 12 };

static void setImageZoom(uint32_t value, uint32_t type)
{
    Fpga::getInstance()->writeRegister(0x401d0, value);
}

static void setImageAwb(uint32_t value, uint32_t type)
{
    uint16_t b = (value) && 0xFF;
    uint16_t r = (value >> 16) && 0xFF;
    /* set r/b config */
    Fpga::getInstance()->writeRegister(AWB_CONFIG_ADDR, r, AWB_CONFIG_R_START_BIT, AWB_CONFIG_R_END_BIT);
    Fpga::getInstance()->writeRegister(AWB_CONFIG_ADDR, b, AWB_CONFIG_B_START_BIT, AWB_CONFIG_B_END_BIT);
    /* start auto white balance by pulse */
    Fpga::getInstance()->writeRegister(AWB_ENABLE_ADDR, AWB_CONFIG_START_VALUE, AWB_CONFIG_BIT, AWB_CONFIG_BIT);
    Fpga::getInstance()->writeRegister(AWB_ENABLE_ADDR, AWB_CONFIG_END_VALUE, AWB_CONFIG_BIT, AWB_CONFIG_BIT);
}



static void setCCMEN(uint32_t value, uint32_t type) {
    Fpga::getInstance()->writeRegister(0x40234, value?0x10000:0);
}


static void setImageDLC(uint32_t index, uint32_t type){
    qDebug()<<__FUNCTION__<<index;
}

static void setImageDPC(uint32_t index, uint32_t type){
    qDebug()<<__FUNCTION__<<index;
}

static void setImageLens(uint32_t index, uint32_t type){
    qDebug()<<__FUNCTION__<<index;
}
